﻿SSVC.Wrap.Dojo.Declare("Viewer", null,
{
	currentPageNumber: null,
	markupPages: null,
	markupToolbar: null,
	markupToolbarDiv: null,
	viewerDiv: null,
	loadedMarkupXml: null,
	viewerType: null,
	messageId: null,
	parentMessageId: null,
	startPage: null,
	isViewFrozen: null,
	viewerMode: null,
	frozenViewContainer: null,//frozenViewContainer
	currFreezeImg: null,//currFreezeImg
	currMarkupPage: null,
	ViewerModes: {
		Creation: "creation",
		Review: "review",
		View: "view"
	},

	constructor: function()
	{
		this.markupPages = {};
		this.loadedMarkupXml = {};
		this.currFreezeImg = document.getElementById("SnapshotImage");
		this.frozenViewContainer = document.getElementById("SnapshotContainer");
		//this.isViewFrozen = false;
	},

	Initialize: function() { },

	AddPage: function(pageNumber, width, height)
	{
		if (!this.CheckPage(pageNumber))
		{
			this.currMarkupPage = new SSVC.MarkupPage();
			this.markupPages[pageNumber] = this.currMarkupPage;

			this.currMarkupPage.position = {
				left: this.currFreezeImg.style.left,
				top: this.currFreezeImg.style.top,
				width: this.currFreezeImg.style.width,
				height: this.currFreezeImg.style.height
			};

			this.currMarkupPage.clientX = 0;
			this.currMarkupPage.clientY = 0;
			this.currMarkupPage.width = this.currMarkupPage.position.width;
			this.currMarkupPage.height = this.currMarkupPage.height;

			this.currMarkupPage.placeAt(this.frozenViewContainer);

			if (this.loadedMarkupXml.hasOwnProperty(pageNumber))
			{
				this.currMarkupPage.applyXML(this.loadedMarkupXml[pageNumber]);
				delete this.loadedMarkupXml[pageNumber];
			}
		}
	},

	CheckPage: function(pageNumber)
	{
		return (this.markupPages[pageNumber] !== undefined);
	},

	UpdatePage: function()
	{
		var width = this.currFreezeImg.offsetWidth;
		var height = this.currFreezeImg.offsetHeight;

		this.currMarkupPage.width = width;
		this.currMarkupPage.height = height;
	},

	Reload: function()
	{
		this.markupPages = {};
		this.loadedMarkupXml = {};

		this.currMarkupPage.removeAt(this.currFreezeImg);
		this.AddPage();
	},

	SetCurrentPage: function(pageNumber)
	{
		this.currentPageNumber = pageNumber;
	},

	SetParentMessageId: function(newMessageId)
	{
		this.parentMessageId = newMessageId;
	},

	LoadMarkupToolbar: function()
	{
		this.markupToolbar = new SSVC.MarkupToolbar();
		this.markupToolbar.placeAt(document.getElementById("MarkupToolbarOuter"));

		var self = this;

		this.markupToolbar.OnClickHighlightButton = function()
		{
			self.Freeze();
			self.updateNotationsSettings({ background: SSVC.Utils.convertHexToRGBA(self.markupToolbar.highlightColor, "0.5") });
			self.currMarkupPage.startDrawing(SSVC.SVG.ActiveElement);
		};
		this.markupToolbar.OnClickTextButton = function()
		{
			self.Freeze();
			self.updateNotationsSettings({ fontSize: 14 });
			self.currMarkupPage.startDrawing(SSVC.SVG.ActiveLabelElement);
		};
		this.markupToolbar.OnClickLineButton = function()
		{
			self.Freeze();
			self.updateNotationsSettings();
			self.currMarkupPage.startDrawing(SSVC.SVG.ActiveScribbleElement);
		};
		this.markupToolbar.OnClickBoxButton = function()
		{
			self.Freeze();
			self.updateNotationsSettings();
			self.currMarkupPage.startDrawing(SSVC.SVG.ActiveElement);
		};
		this.markupToolbar.OnClickEllipseButton = function()
		{
			self.Freeze();
			self.updateNotationsSettings();
			self.currMarkupPage.startDrawing(SSVC.SVG.ActiveEllipseElement);
		};
		this.markupToolbar.OnClickSelectButton = function()
		{
			self.Freeze();
			self.currMarkupPage.startEditing();
		};
		this.markupToolbar.OnClickClearButton = function()
		{
			if (self.viewerMode === self.ViewerModes.Creation ||
				self.viewerMode === self.ViewerModes.Review)
				if (top.aras.confirm(SSVC.Utils.GetResource("mark_tb_lose_unsaved_markup")))
				{
					self.viewerMode = self.ViewerModes.View;

					self.markupToolbar.resetAllButtonsState();

					self.ClearPage(1);
					self.Unfreeze();
					self.onWindowResizeEventHandler();
				}
		};

		this.markupToolbarDiv = this.markupToolbar.domNode;
	},

	updateNotationsSettings: function(additionalSettings)
	{
		if (!additionalSettings)
			additionalSettings = {};

		additionalSettings.strokeWidth = this.markupToolbar.getStrokeWidth();
		additionalSettings.lineColor = this.markupToolbar.lineColor;
		additionalSettings.strokeDash = this.markupToolbar.getStrokeDash();
		additionalSettings.lineType = this.markupToolbar.lineType;
		additionalSettings.background = (additionalSettings.background) ? additionalSettings.background : "transparent";

		this.currMarkupPage.setDrawableSettings(additionalSettings);
	},

	LoadMarkup: function(markupXml, pagePar)
	{
		var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(markupXml);

		var svgXmlNodes = xmlDoc.getElementsByTagName("svg");

		if (svgXmlNodes.length !== 1)
			return;

		var page = pagePar ? pagePar : svgXmlNodes[0].getAttribute("page");
		var markupPageXml = SSVC.Wrap.Dojo.Xml.innerXML(svgXmlNodes[0]);

		if (this.CheckPage(page))
			this.currMarkupPage.applyXML(markupPageXml);
		else
			this.loadedMarkupXml[page] = markupPageXml;

		this.onWindowResizeEventHandler();
	},

	ShowMarkupToolbar: function()
	{
		if (this.markupToolbar)
			this.markupToolbar.domNode.style.display = "inline";
	},

	HideMarkupToolbar: function()
	{
		if (this.markupToolbar)
			this.markupToolbar.domNode.style.display = "none";
	},

	ShowFrozenPanel: function()
	{
		if (this.frozenViewContainer)
			this.frozenViewContainer.style.display = "block";
		else
		{
			this.frozenViewContainer = document.getElementById("SnapshotContainer");
			this.ShowFrozenPanel();
		}
	},

	HideFrozenPanel: function()
	{
		if (this.frozenViewContainer)
			this.frozenViewContainer.style.display = "none";
	},

	SendComment: function(text, communityId, onAfterSaveCallback)
	{
		var idArray = this.produceSnapshotThumbnailFiles(this.getSnapshotPage(1));
		var snapshotId = idArray[0];
		var thumbnailId = idArray[1];

		var instanceDocument = SSVC.Utils.Page.GetInstanceDocument();

		var smProperties = {};
		smProperties.classification = "Markup";
		smProperties.from_identity = this.getLoggedIdentityId();
		smProperties.markup = this.GetMarkupXml();
		smProperties.message_text = text;
		smProperties.parent_id = this.parentMessageId || null;
		smProperties.snapshot = "vault:///?fileId=" + snapshotId;
		smProperties.source_id = communityId;
		smProperties.source_major_rev = instanceDocument.thisItem.getProperty("major_rev", "");
		smProperties.source_generation = instanceDocument.thisItem.getProperty("generation", "");
		smProperties.source_state = instanceDocument.thisItem.getProperty("state", "");
		smProperties.thumbnail = "vault:///?fileId=" + thumbnailId;
		smProperties.view_state = "<view_state>" + this.currentPageNumber + "</view_state>";

		var secureMessage = new SSVC.ArasHelper.SecureMessage("add");
		secureMessage.setItemBeforeSaving(smProperties);
		secureMessage.fill();
		secureMessage.buildStructure();

		if (secureMessage.isError())
			return;

		this.viewerMode = SSVC.Utils.Enums.ViewerMode.View;

		top.aras.AlertSuccess(SSVC.Utils.GetResource("pdfv_markup_saved_successfully"));
		this.Reload(1);
		this.Unfreeze();

		this.markupToolbar.resetAllButtonsState();

		if (onAfterSaveCallback)
			onAfterSaveCallback(secureMessage);
	},

	GetMarkupXml: function(pageNumberPar)
	{
		pageNumberPar = pageNumberPar || 1;
		if (this.markupPages.hasOwnProperty(pageNumberPar))
		{
			var xmlDoc = this.currMarkupPage.getXML();
			if (xmlDoc.childNodes.length === 0)
				return "";
			xmlDoc.setAttribute("page", this.currentPageNumber);
			return SSVC.Wrap.Dojo.Xml.innerXML(xmlDoc);
		}

		return "";
	},

	IsMarkupPresented: function()
	{
		if (!this.CheckPage(1))
			return false;

		return this.currMarkupPage && this.currMarkupPage.childs.length > 0;
	},

	DetectSVGBoundingRect: function()
	{
		if (!this.CheckPage(1))
			return;

		var svgChilds = this.currMarkupPage.childs;

		if (!svgChilds || svgChilds.length <= 0)
			return;

		var left = svgChilds[0].X,
			top = svgChilds[0].Y,
			right = svgChilds[0].X + svgChilds[0].OX,
			bottom = svgChilds[0].Y + svgChilds[0].OY;

		for (var i = 1; i < svgChilds.length; i++)
		{
			left = Math.min(left, svgChilds[i].X);
			top = Math.min(top, svgChilds[i].Y);
			right = Math.max(right, svgChilds[i].X + svgChilds[i].OX);
			bottom = Math.max(bottom, svgChilds[i].Y + svgChilds[i].OY);
		}

		var res =
			{
				left: left,
				top: top,
				width: right - left,
				height: bottom - top
			};

		return res;
	},

	OnWindowResizeSnapshotBehavior: function(viewerFrameRect)
	{
		if (this.viewerMode !== this.ViewerModes.Creation &&
			this.viewerMode !== this.ViewerModes.Review)
			return;

		var newWidth, newHeight, newTop, newLeft;
		var fpRatio = viewerFrameRect.width / viewerFrameRect.height;
		var imgRatio = this.currFreezeImg.naturalWidth / this.currFreezeImg.naturalHeight;

		if (this.viewerMode === this.ViewerModes.Creation)
		{
			if (fpRatio >= 1.0 && imgRatio * viewerFrameRect.height <= viewerFrameRect.width ||
				fpRatio < 1.0 && viewerFrameRect.width / imgRatio > viewerFrameRect.height)
			{
				newHeight = viewerFrameRect.height;
				newWidth = imgRatio * newHeight;
				newTop = 0;
				newLeft = 0.5 * (viewerFrameRect.width - newWidth);
			}
			else
			{
				newWidth = viewerFrameRect.width;
				newHeight = newWidth / imgRatio;
				newTop = 0.5 * (viewerFrameRect.height - newHeight);
				newLeft = 0;
			}
		}

		var maxMoveLength;

		if (this.viewerMode === this.ViewerModes.Review)
		{
			var rect = this.DetectSVGBoundingRect();

			if (fpRatio >= 1.0 && imgRatio * viewerFrameRect.height <= viewerFrameRect.width ||
				fpRatio < 1.0 && viewerFrameRect.width / imgRatio > viewerFrameRect.height)
			{
				newHeight = viewerFrameRect.height;
				newWidth = imgRatio * newHeight;
				newTop = 0;

				if (!rect)
					newLeft = 0.5 * (viewerFrameRect.width - newWidth);
				else
				{
					var markupHorCenter = 0.5 * rect.width;
					var frameHorCenter = 0.5 * viewerFrameRect.width;
					maxMoveLength = viewerFrameRect.width - newWidth;

					if (frameHorCenter - markupHorCenter <= 0)
						newLeft = 0;
					else
						if (frameHorCenter - markupHorCenter < maxMoveLength)
							newLeft = frameHorCenter - markupHorCenter;
						else
							newLeft = maxMoveLength;
				}
			}
			else
			{
				newWidth = viewerFrameRect.width;
				newHeight = newWidth / imgRatio;
				newLeft = 0;

				if (!rect)
					newTop = 0.5 * (viewerFrameRect.height - newHeight);
				else
				{
					var markupVerCenter = 0.5 * rect.height;
					var frameVerCenter = 0.5 * viewerFrameRect.height;
					maxMoveLength = viewerFrameRect.height - newHeight;

					if (frameVerCenter - markupVerCenter <= 0)
						newTop = 0;
					else
						if (frameVerCenter - markupVerCenter < maxMoveLength)
							newTop = frameVerCenter - markupVerCenter;
						else
							newTop = maxMoveLength;
				}
			}
		}
		this.currFreezeImg.style.top = newTop + "px";
		this.currFreezeImg.style.left = newLeft + "px";
		this.currFreezeImg.style.width = newWidth + "px";
		this.currFreezeImg.style.height = newHeight + "px";

		this.AddPage();

		if (this.currMarkupPage)
		{
			var prevWidth = this.currMarkupPage.width;
			var prevHeight = this.currMarkupPage.height;
			this.currMarkupPage.scale(newWidth / prevWidth, newHeight / prevHeight);
		}
	},

	getLoggedIdentityId: function()
	{
		var userNd = top.aras.getLoggedUserItem();
		var identityNd = userNd.selectSingleNode("Relationships/Item[@type='Alias']/related_id/Item[@type='Identity']");
		if (!identityNd) return;

		return identityNd.getAttribute("id");
	},

	produceSnapshotThumbnailFiles: function(original)
	{
		var imgItm = top.aras.newIOMItem("Document", "VC_SaveThumbnail");
		imgItm.setProperty("png_data", original);
		imgItm = imgItm.apply();

		if (imgItm.isError())
		{
			top.aras.AlertError(imgItm.getErrorString());
			return null;
		}

		return imgItm.getResult().split(",");
	}
});

SSVC.Wrap.Dojo.SetObject("SSVC.PdfViewer", (function()
{
	var intervalObject = {};

	return SSVC.Wrap.Dojo.Declare("PdfViewer", Viewer, {
		constructor: function(viewerParamsObject)
		{
			this.messageId = viewerParamsObject.messageId;
			this.parentMessageId = viewerParamsObject.parentMessageId;
			this.startPage = viewerParamsObject.startPage;
			this.viewerMode = viewerParamsObject.viewerMode;
			if (SSVC.Utils.isNullOrUndefined(this.viewerMode))
				throw new Error("PdfViewer: viewerMode is undefined");
			this.isViewFrozen = false;

			this.viewerType = "pdf";
		},

		Initialize: function()
		{
			function frozenPanelLoaded()
			{
				if (SSVC.Wrap.PDFjs.PagesCount() >= self.currentPageNumber && SSVC.Wrap.PDFjs.IsViewFinished(self.currentPageNumber))
				{
					self.frozenViewContainer = document.getElementById("FrozenPanel");

					self.currFreezeImg = document.getElementById("SnapshotImage");

					if (self.viewerMode === self.ViewerModes.Review)
					{
						self.AddPage();
						self.SetCurrentPage(1);
						self.Freeze(SSVC.Wrap.Dojo.Hitch(self, "loadMarkupFromMessage"));

					}



					clearInterval(intervalId);
				}
			}

			window.addEventListener("resize", SSVC.Wrap.Dojo.Hitch(this, "onWindowResizeEventHandler"));
			window.addEventListener("pagechange", SSVC.Wrap.Dojo.Hitch(this, "onPageChangeEventHandler"));

			this.currentPageNumber = this.startPage;

			this.LoadMarkupToolbar();

			this.viewerDiv = document.getElementById("outerContainer");
			this.viewerDiv.style.height = (document.body.offsetHeight - this.markupToolbarDiv.offsetHeight) + "px";

			var intervalId = setInterval(frozenPanelLoaded, 200);

			var self = this;
			
		},

		SetCurrentPage: function(pageNumber, callback)
		{
			function currentPageChanged()
			{
				if (SSVC.Wrap.PDFjs.IsViewFinished(pageNumber))
				{
					callback();

					clearInterval(intervalId);
				}
			}

			if (this.currentPageNumber === pageNumber)
				return;

			this.currentPageNumber = pageNumber;

			if (SSVC.Wrap.PDFjs.GetCurrentPageNumber() === pageNumber)
				return;

			SSVC.Wrap.PDFjs.SetCurrentPageNumber(pageNumber);

			if (!callback)
				return;

			var intervalId = setInterval(currentPageChanged, 200);

			var self = this;

		},

		Freeze: function()
		{
			if (this.viewerMode === this.ViewerModes.Creation) return;
			this.viewerMode = this.ViewerModes.Creation;
			//if (this.isViewFrozen)
			//{
			//	this.onWindowResizeEventHandler();
			//	return;
			//}
			this.ShowFrozenPanel();
			var rect = document.getElementById("outerContainer").getBoundingClientRect();
			this.frozenViewContainer.style.top = rect.top + "px";
			this.frozenViewContainer.style.left = rect.left + "px";
			this.frozenViewContainer.style.width = "100%";
			this.frozenViewContainer.style.height = rect.height + "px";

			//this.currFreezeImg.onload = imgLoaded;
			this.currFreezeImg.src = SSVC.Wrap.PDFjs.GetPageCanvas(this.currentPageNumber).toDataURL();
			//this.currFreezeImg.load();
			var self = this;
			function imgLoaded()
			{
				self.isViewFrozen = true;
				self.viewerDiv.style.display = "none";

				self.onWindowResizeEventHandler();
			}
			imgLoaded();

			
		},

		FreezeAndLoadMarkupFromMessage: function(messageIdPar)
		{
			if (!messageIdPar)
				return;

			this.messageId = messageIdPar;

			var secureMessage = SSVC.VisualCollaborationTool.createSecureMessage();
			secureMessage.loadById(messageIdPar);

			var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(secureMessage.getProperty("view_state", ""));
			var pageNumber = Number(SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.documentElement)) || 1;

			if (this.currentPageNumber !== pageNumber)
				this.SetCurrentPage(pageNumber, SSVC.Wrap.Dojo.Hitch(this, "Freeze", SSVC.Wrap.Dojo.Hitch(this, "loadMarkupFromMessage")));
			else
				this.Freeze(SSVC.Wrap.Dojo.Hitch(this, "loadMarkupFromMessage"));
		},

		UnfreezeAndLoadMarkupFromMessage: function(messageIdPar)
		{
			if (!messageIdPar)
				return;

			this.Unfreeze();

			this.FreezeAndLoadMarkupFromMessage(messageIdPar);
		},

		Unfreeze: function()
		{
			this.isViewFrozen = false;
			this.viewerDiv.style.display = "block";

			SSVC.Wrap.PDFjs.Cleanup();

			this.HideFrozenPanel();
		},

		loadMarkupFromMessage: function()
		{
			if (SSVC.Utils.isNullOrUndefined(this.messageId))
				return;

			var secureMessage = SSVC.VisualCollaborationTool.createSecureMessage();
			secureMessage.loadById(this.messageId);

			var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(secureMessage.getProperty("view_state", ""));
			var pageNumber = Number(SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.documentElement)) || 1;
			this.currentPageNumber = pageNumber;

			var markupXml = secureMessage.getProperty("markup", "");
			if (markupXml === "")
				return;

			this.LoadMarkup(markupXml, 1);
		},

		getSnapshotPage: function(pageNumber)
		{
			var svgXml = this.GetMarkupXml();

			var canvas = document.createElement("canvas");
			canvas.setAttribute("width", this.currFreezeImg.clientWidth);
			canvas.setAttribute("height", this.currFreezeImg.clientHeight);
			var ctx = canvas.getContext("2d");

			ctx.drawImage(this.currFreezeImg, 0, 0, this.currFreezeImg.clientWidth, this.currFreezeImg.clientHeight);
			ctx.drawSvg(svgXml);

			return canvas.toDataURL();
		},

		onWindowResizeEventHandler: function()
		{
			var calculatedHeight = document.body.offsetHeight - this.markupToolbarDiv.offsetHeight;
			this.viewerDiv.style.height = calculatedHeight + "px";
			this.frozenViewContainer.style.top = this.markupToolbarDiv.offsetHeight + "px";
			this.frozenViewContainer.style.height = calculatedHeight + "px";

			this.OnWindowResizeSnapshotBehavior({ width: this.frozenViewContainer.clientWidth, height: this.frozenViewContainer.clientHeight, scale: true });
		},

		onPageChangeEventHandler: function(ev)
		{
			this.currentPageNumber = ev.pageNumber;
		}
	});
})());

SSVC.Wrap.Dojo.SetObject("SSVC.HoopsViewer", (function()
{
	function hoopsContainer()
	{
		var container;

		this.CreateHTMLContainer = function()
		{
			if (SSVC.Utils.isIE())
			{
				container = document.createElement("object");
				container.id = "hoopsContainer";
				container.setAttribute("width", "100%");
				container.setAttribute("codebase", "http://www.google.com");
				container.setAttribute("classid", "CLSID:E0A900DF-9611-4446-86BD-4B1D47E7DB2A");
				container.setAttribute("style", "top:0px; right:0px; bottom:0px; left:0px; border-style:none;");
			}
			else
			{
				container = document.createElement("iframe");
				container.id = "hoopsContainer";
				container.setAttribute("width", "100%");
				container.setAttribute("height", "100%");
				container.setAttribute("style", "top:0px; right:0px; bottom:0px; left:0px; border-style:none;");
			}
			document.body.appendChild(container);
		};

		this.SetMessageListener = function(f)
		{
			if (SSVC.Utils.isIE())
				container.onmessage = f;
			else
				window.addEventListener("message", f, false);
		};

		this.SetAttribute = function(name, value)
		{
			container.setAttribute(name, value);
		};

		this.PostMessage = function(msg)
		{
			if (SSVC.Utils.isIE())
				container.postMessage(msg);
			else
				window.postMessage(msg, "*");
		};

		Object.defineProperty(hoopsContainer.prototype, "src",
		{
			get: function() { return container.src; },
			set: function(val) { container.src = val; }
		});
		Object.defineProperty(hoopsContainer.prototype, "offsetWidth",
		{
			get: function() { return container.offsetWidth; },
			set: function(val) { container.offsetWidth = val; }
		});
		Object.defineProperty(hoopsContainer.prototype, "offsetHeight",
		{
			get: function() { return container.offsetHeight; },
			set: function(val) { container.offsetHeight = val; }
		});
		Object.defineProperty(hoopsContainer.prototype, "style",
		{
			get: function() { return container.style; },
			set: function(val) { container.style = val; }
		});
	}

	function createAction(action)
	{
		var xml = SSVC.Wrap.Dojo.Xml.parse("<msg></msg>");
		addTextNode(xml.documentElement, "action", action);
		addTextNode(xml.documentElement, "msg_src", "markup_viewer");
		addTextNode(xml.documentElement, "msg_dest", "hoops_viewer");
		return xml;
	}

	function addTextNode(toNode, newNodeName, val)
	{
		var textNode = toNode.ownerDocument.createTextNode(newNodeName);
		textNode.nodeValue = val;

		var node = toNode.ownerDocument.createElement(newNodeName);
		node.appendChild(textNode);

		toNode.appendChild(node);
		return node;
	}

	function outerXML(xmlDoc)
	{
		return SSVC.Wrap.Dojo.Xml.innerXML(xmlDoc);
	}

	var theHoopsContainer = new hoopsContainer();

	var textualMessage = "", markupXml = "", svgXml = "";

	var fileUrl, documentId, documentType, fileId, communityId;
	var onAfterSaveCallback = null;
	var viewerReplaced = false;

	return SSVC.Wrap.Dojo.Declare("HoopsViewer", Viewer, {
		constructor: function(viewerParamsObject)
		{
			this.inherited(arguments);

			//Copy parameters
			fileUrl = viewerParamsObject.fileUrl;
			documentId = viewerParamsObject.documentId;
			documentType = viewerParamsObject.documentType;
			fileId = viewerParamsObject.fileId;
			this.messageId = viewerParamsObject.messageId;
			this.parentMessageId = viewerParamsObject.parentMessageId;
			this.viewerMode = viewerParamsObject.viewerMode;
			if (SSVC.Utils.isNullOrUndefined(this.viewerMode))
				throw new Error("HoopsViewer: viewerMode is undefined");

			this.viewerType = "hoops";
		},

		Initialize: function()
		{
			window.addEventListener("resize", SSVC.Wrap.Dojo.Hitch(this, "onWindowResizeEventHandler"));

			this.LoadMarkupToolbar();

			var viewState;

			if (this.messageId)
			{
				var secureMessageObj = SSVC.VisualCollaborationTool.createSecureMessage();
				secureMessageObj.loadById(this.messageId);

				viewState = secureMessageObj.getProperty("view_state", "");
				var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(viewState);
				viewState = SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.getElementsByTagName("view_state")[0]);
				markupXml = this.viewerMode === this.ViewerModes.Review ? secureMessageObj.getProperty("markup", "") : "";
			}

			theHoopsContainer.CreateHTMLContainer();

			var loc = window.location.href;
			theHoopsContainer.src = loc.substring(0, loc.lastIndexOf("/")) + "/../../../javascript/hoopswebviewer/hoops_web_viewer.html?" + (this.messageId ? viewState : "null") + "&" + fileUrl;
			theHoopsContainer.SetMessageListener(SSVC.Wrap.Dojo.Hitch(this, "onHoopsMessage"));

			var height = (document.body.offsetHeight - this.markupToolbarDiv.offsetHeight - 5) + "px";
			theHoopsContainer.SetAttribute("height", height);

			this.currFreezeImg.setAttribute("height", height);
		},

		ReloadViewer: function(messageId)
		{
			if (SSVC.Utils.isNullOrUndefined(messageId))
				throw new Error("ReloadViewer: messageId is undefined");

			this.messageId = messageId;
			var secureMessageObj = SSVC.VisualCollaborationTool.createSecureMessage();
			secureMessageObj.loadById(this.messageId);

			var viewState = secureMessageObj.getProperty("view_state", "");
			var xmlDoc = SSVC.Wrap.Dojo.Xml.parse(viewState);
			viewState = SSVC.Wrap.Dojo.Xml.textContent(xmlDoc.getElementsByTagName("view_state")[0]);
			markupXml = this.viewerMode === this.ViewerModes.Review ? secureMessageObj.getProperty("markup", "") : "";

			this.frozenViewContainer.style.display = "none";
			theHoopsContainer.style.display = "block";

			this.pointViewerCamera(viewState);
		},

		Reload: function(pageNumber)
		{
			this.inherited(arguments);

			markupXml = "";
		},

		Freeze: function()
		{
			if (this.viewerMode === this.ViewerModes.Creation) return;
			this.viewerMode = this.ViewerModes.Creation;
			this.replaceHoopsObjectByScreenshot();
		},

		Unfreeze: function()
		{
			this.replaceScreenshotByHoopsObject();
		},

		SendComment: function(text, communityIdPar, callback)
		{
			communityId = communityIdPar;
			onAfterSaveCallback = callback;

			textualMessage = text;
			markupXml = this.GetMarkupXml();
			svgXml = this.currMarkupPage.getInnerXML();

			var action = createAction("save");
			theHoopsContainer.PostMessage(outerXML(action));
		},

		replaceHoopsObjectByScreenshot: function()
		{
			if (!viewerReplaced)
			{
				var action = createAction("replaceViewerBySnapshot");
				theHoopsContainer.PostMessage(outerXML(action));
			}
			else
			{
				this.onWindowResizeEventHandler();
			}
		},

		replaceScreenshotByHoopsObject: function()
		{
			if (viewerReplaced)
			{
				this.frozenViewContainer.style.display = "none";
				theHoopsContainer.style.display = "block";

				viewerReplaced = false;
			}

			this.onWindowResizeEventHandler();
		},

		pointViewerCamera: function(camera)
		{
			var action = createAction("pointViewerCamera");
			addTextNode(action.documentElement, "camera", camera);
			theHoopsContainer.PostMessage(outerXML(action));
		},

		onHoopsMessage: function(msg)
		{
			var xml = SSVC.Wrap.Dojo.Xml.parse(msg.data);
			var destination = SSVC.Wrap.Dojo.Xml.textContent(xml.getElementsByTagName("msg_dest")[0]);
			if (destination !== "markup_viewer")
				return;

			var action = SSVC.Wrap.Dojo.Xml.textContent(xml.getElementsByTagName("action")[0]);
			switch (action)
			{
				case "loaded":
					console.log("loaded");
					viewerReplaced = false;

					if (this.viewerMode === this.ViewerModes.Review)
					{
						this.AddPage();
						this.SetCurrentPage(1);
						var action2 = createAction("replaceViewerBySnapshot");
						theHoopsContainer.PostMessage(outerXML(action2));
					}
					break;
				case "replaceViewerBySnapshot":
					theHoopsContainer.style.display = "none";
					if (SSVC.Utils.isIE())
					{
						this.currFreezeImg.src = SSVC.Wrap.Dojo.Xml.textContent(xml.getElementsByTagName("snapshot")[0]);
						this.frozenViewContainer.style.display = "block";
					}

					this.AddPage();
					this.SetCurrentPage(1);

					if (markupXml !== "")
						this.LoadMarkup(markupXml);

					viewerReplaced = true;
					this.onWindowResizeEventHandler();
					break;
				case "replaceSnapshotByViewer":
					this.frozenViewContainer.style.display = "none";
					theHoopsContainer.style.display = "block";

					viewerReplaced = false;
					break;
				case "save":
					this.saveSecureMessage(xml);

					this.replaceScreenshotByHoopsObject();
					this.Reload(1);

					markupXml = "";

					this.markupToolbar.resetAllButtonsState();

					this.viewerMode = SSVC.Utils.Enums.ViewerMode.View;
					break;
			}
		},

		saveSecureMessage: function(xml)
		{
			var doc = top.aras.IomInnovator.newItem(documentType, "get");
			doc.setProperty("id", documentId);
			doc = doc.apply();

			var idArray = this.produceSnapshotThumbnailFiles(this.getSnapshotPage(1));
			var snapshotId = idArray[0];
			var thumbnailId = idArray[1];

			var viewState = "<view_state>" + SSVC.Wrap.Dojo.Xml.textContent(xml.getElementsByTagName("view_state")[0]) + "</view_state>";

			var smProperties = {};
			smProperties.classification = "Markup";
			smProperties.from_identity = this.getLoggedIdentityId();
			smProperties.markup = markupXml;
			smProperties.message_text = textualMessage;
			smProperties.parent_id = this.parentMessageId || null;
			smProperties.snapshot = "vault:///?fileId=" + snapshotId;
			smProperties.source_id = communityId;
			smProperties.source_major_rev = doc.getProperty("major_rev", "");
			smProperties.source_generation = doc.getProperty("generation", "");
			smProperties.source_state = doc.getProperty("state", "");
			smProperties.thumbnail = "vault:///?fileId=" + thumbnailId;
			smProperties.view_state = viewState;

			var secureMessage = new SSVC.ArasHelper.SecureMessage("add");
			secureMessage.setItemBeforeSaving(smProperties);
			secureMessage.fill();
			secureMessage.buildStructure();

			if (secureMessage.isError())
				return;

			top.aras.AlertSuccess(SSVC.Utils.GetResource("hoops_markup_saved_successfully"));

			if (onAfterSaveCallback)
			{
				onAfterSaveCallback(secureMessage);
				onAfterSaveCallback = null;
			}
		},

		getSnapshotPage: function(pageNumber)
		{
			var img = document.createElement("img");
			img.src = this.currFreezeImg.src;

			var width = (this.frozenViewContainer.style.display === "none") ? theHoopsContainer.offsetWidth : this.currFreezeImg.offsetWidth;
			var height = (this.frozenViewContainer.style.display === "none") ? theHoopsContainer.offsetHeight : this.currFreezeImg.offsetHeight;

			var canvas = document.createElement("canvas");
			canvas.setAttribute("width", width);
			canvas.setAttribute("height", height);
			var ctx = canvas.getContext("2d");

			ctx.drawImage(img, 0, 0, width, height);
			ctx.drawSvg(markupXml);

			return canvas.toDataURL();
		},

		onWindowResizeEventHandler: function()
		{
			var height = document.body.offsetHeight - this.markupToolbarDiv.offsetHeight;
			this.frozenViewContainer.style.height = height + "px";

			if (!viewerReplaced)
			{
				this.currFreezeImg.style.height = height + "px";
				theHoopsContainer.style.height = height + "px";
			}

			this.OnWindowResizeSnapshotBehavior({ width: this.frozenViewContainer.clientWidth, height: this.frozenViewContainer.clientHeight, scale: true });
		}
	});
})());

SSVC.Wrap.Dojo.SetObject("SSVC.ImageViewer", (function()
{
	return SSVC.Wrap.Dojo.Declare("ImageViewer", Viewer,
	{
		snapshotFileId: null,
		snapshotFileUrl: null,

		constructor: function(viewerParamsObject)
		{
			this.inherited(arguments);

			this.messageId = viewerParamsObject.messageId;
			this.parentMessageId = viewerParamsObject.parentMessageId;
			this.viewerMode = viewerParamsObject.viewerMode;
			if (SSVC.Utils.isNullOrUndefined(this.viewerMode))
				throw new Error("ImageViewer: viewerMode is undefined");
			this.snapshotFileId = viewerParamsObject.fileId;
			this.snapshotFileUrl = viewerParamsObject.fileUrl;
			this.startPage = 1;

			this.viewerType = "image";
		},

		Initialize: function()
		{
			this.LoadMarkupToolbar();
			if (this.viewerMode === this.ViewerModes.Review)
			{
				this.AddPage();
				this.SetCurrentPage(1);
			}
			if (this.viewerMode === this.ViewerModes.Review)
				SSVC.Wrap.Dojo.On(this.currFreezeImg, "load", SSVC.Wrap.Dojo.Partial(this.LoadMarkupFromMessage, this.messageId, this));
			SSVC.Wrap.Dojo.On(this.currFreezeImg, "load", SSVC.Wrap.Dojo.Hitch(this, "onWindowResizeEventHandler"));
			SSVC.Wrap.Dojo.Attr(this.currFreezeImg, "src", this.snapshotFileUrl);

			SSVC.Wrap.Dojo.On(window, "resize", SSVC.Wrap.Dojo.Hitch(this, "onWindowResizeEventHandler"));
		},

		LoadMarkupFromMessage: function(messageIdPar, self)
		{
			if (SSVC.Utils.isNullOrUndefined(messageIdPar))
				return;

			if (!self)
				self = this;

			self.messageId = messageIdPar;

			var secureMessage = SSVC.VisualCollaborationTool.createSecureMessage();
			secureMessage.loadById(self.messageId);
			var markupXml = secureMessage.getProperty("markup", "");

			self.LoadMarkup(markupXml);
		},

		getSnapshotPage: function(pageNumber)
		{
			var canvas = document.createElement("canvas");
			canvas.setAttribute("width", this.currFreezeImg.offsetWidth);
			canvas.setAttribute("height", this.currFreezeImg.offsetHeight);
			var ctx = canvas.getContext("2d");

			ctx.drawImage(this.currFreezeImg, 0, 0, this.currFreezeImg.offsetWidth, this.currFreezeImg.offsetHeight);

			var svgXml = this.GetMarkupXml();
			ctx.drawSvg(svgXml);

			return canvas.toDataURL();
		},

		onWindowResizeEventHandler: function()
		{
			if (this.viewerMode === SSVC.Utils.Enums.ViewerMode.View)
			{
				this.frozenViewContainer.style.overflow = "visible";
				this.currFreezeImg.style.top = "0px";
				this.currFreezeImg.style.left = "0px";
				this.currFreezeImg.style.width = this.currFreezeImg.naturalWidth + "px";
				this.currFreezeImg.style.height = this.currFreezeImg.naturalHeight + "px";
			}
			else
			{
				this.frozenViewContainer.style.overflow = "hidden";
			}

			var calculatedHeight = document.body.offsetHeight - this.markupToolbarDiv.offsetHeight;
			this.frozenViewContainer.style.height = calculatedHeight + "px";

			this.OnWindowResizeSnapshotBehavior({ width: this.frozenViewContainer.clientWidth, height: this.frozenViewContainer.clientHeight });
		},

		Freeze: function()
		{
			if (this.viewerMode === this.ViewerModes.Creation) return;
			this.viewerMode = this.ViewerModes.Creation;
			this.isViewFrozen = true;
			this.onWindowResizeEventHandler();
		},

		Unfreeze: function()
		{
			this.isViewFrozen = false;
			this.onWindowResizeEventHandler();
		},

		UnfreezeAndLoadMarkupFromMessage: function(messageIdPar)
		{
			this.LoadMarkupFromMessage(messageIdPar);
		},

		FreezeAndLoadMarkupFromMessage: function(messageIdPar)
		{
			this.LoadMarkupFromMessage(messageIdPar);
		}
	});
})());